package com.arcticcoding.telemetrie;

import com.arcticcoding.telemetrie.comm.GPSResponse;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.location.LocationProvider;
import android.os.Bundle;
import android.util.Log;

/**
 * 
 * @author steffenschuhmann
 * @version 0.5
 */
public class GeoService extends TelemetrieService {
	private static final String 	TAG = "com.arcticcoding.telemetrie.GeoService";
	private TelemetrieProvider 		provider;
	private LocationManager 		manager;
	private GeoListener 			gpsListener 	= null;
	private GeoListener 			passiveListener = null;
	private GeoListener 			networkListener = null;
	
	/**
	 * Never call this constructor, it is needed by the TelemetrieProvider
	 */
	public GeoService() {
		Log.d(TAG, "Empty constructor of GeoService called");
	}
	
	public GeoService(TelemetrieProvider provider) {
		this.provider = provider;
		provider.getApplicationContext();
		manager = (LocationManager) provider.getApplicationContext().getSystemService(
				Context.LOCATION_SERVICE);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public boolean equals(Object o) {
		if(o instanceof GeoService)
			return true;
		
		return false;
	}
	
	/**
	 * Starts the GPS 
	 * 
	 * @return
	 */
	public boolean startGPS() {
		if(gpsListener == null) {
			gpsListener = new GeoListener();
			manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 
					1, 1, gpsListener);
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Start the network service
	 * 
	 * @return
	 */
	public boolean startNetwork() {
		if(networkListener == null) {
			networkListener = new GeoListener();
			manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,
					1, 1, networkListener);
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Starts the passive location scan
	 * 
	 * @return
	 */
	public boolean startPassive() {
		if(passiveListener == null) {
			passiveListener = new GeoListener();
			manager.requestLocationUpdates(LocationManager.PASSIVE_PROVIDER,
					1, 1, passiveListener);
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Stops the GPS service
	 * @return
	 */
	public boolean stopGPS() {
		if(gpsListener != null) {
			manager.removeUpdates(gpsListener);
			gpsListener = null;
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Stops the Networkservice
	 * 
	 * @return
	 */
	public boolean stopNetwork() {
		if(networkListener != null) {
			manager.removeUpdates(networkListener);
			networkListener = null;
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Stops the Passive location service
	 * @return
	 */
	public boolean stopPassive() {
		if(passiveListener != null) {
			manager.removeUpdates(passiveListener);
			passiveListener = null;
			return true;
		} else {
			return false;
		}
	}
	
	/**
	 * Is called when locationdata has changed
	 * 
	 * @param location the new Location
	 */
	protected void valueHasChanged(Location location) {
		// Do dat notify stuff
		GPSResponse response;
		
		response = new GPSResponse(GPSResponse.Type.LOCATION, location);
		
		provider.valueHasChanged(response);
	}
	
	/**
	 * {@inheritDoc}
	 */
	@Override
	public void shutdown() {
		stopGPS();
		stopNetwork();
		stopPassive();
		super.shutdown();
	}
	
	/**
	 * Implementation of the LocationListener, the new locations are passed to the 
	 * valueHasChanged method and post on the provider. 
	 * 
	 * @author steffenschuhmann
	 * @version 1.0
	 */
	private class GeoListener implements LocationListener {

		private static final String TAG = "com.arcticcoding.nxtphone.GeoService.GeoListener";

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onLocationChanged(Location location) {
			Log.d(TAG, "New Location, provider: " + location.getProvider());
			valueHasChanged(location);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onProviderDisabled(String provider) {
			Log.d(TAG, "Location provider disabled: " + provider);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onProviderEnabled(String provider) {
			Log.d(TAG, "Location provider enabled: " + provider);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onStatusChanged(String provider, int status, Bundle extras) {
			switch(status) {
				case LocationProvider.AVAILABLE:
						Log.d(TAG, "Location provider available: " + provider);
				break;
				case LocationProvider.OUT_OF_SERVICE:
					Log.d(TAG, "Location provider out of service: " + provider);
				break;
				case LocationProvider.TEMPORARILY_UNAVAILABLE:
					Log.d(TAG, "Location provider temporarly unavailable: " + provider);
				break;
			}
		}
	}
}
